#!/usr/bin/env python
#
# Copyright 2009 Acumino - http://www.acumino.com/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from config import config
import cgi, os, sys
sys.path.insert(0, './lib')

import wsgiref.handlers

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import login_required

for library in config.content['template_libraries']:
	template.register_template_library(library)

from google.appengine.ext.db import djangoforms

_DEBUG = True

class Content(db.Model):
  slug = db.StringProperty()
  lang = db.StringProperty(default=config.content['default_language']
    ,choices=config.content['languages'].keys())
  title = db.StringProperty()
#  summary = db.TextProperty()
  body = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  owner = db.UserProperty(auto_current_user_add=True)

  def get_latest(self, slug):
    try:
      return db.Query(Content). \
               order('-created'). \
               filter('slug =', slug).fetch(limit=1)[0]
    except IndexError:
      return None

class ContentForm(djangoforms.ModelForm):
  class Meta:
    model = Content
    exclude = ['created', 'slug', 'owner']

class BaseRequestHandler(webapp.RequestHandler):
  """Centralises template generation

  Combines supplied template_values with defaults and renders specified template.
  """
  def generate(self, template_file, values={}, mime_type='text/html'):
    defaults = {
      'app_root': os.path.dirname(__file__)[:-1],
      'request': self.request,
      'user': users.get_current_user(),
      'login_url': users.create_login_url(self.request.uri),
      'logout_url': users.create_logout_url(self.request.uri),
      'application_name': config.content['branding']['name'],
      'mime_type': 'text/html'
    }
    values.update(defaults)
    path = os.path.join(os.path.dirname(__file__), os.path.join( \
      'layouts/simple', template_file))
    self.response.headers['Content-Type'] = mime_type
    self.response.out.write(template.render(path, values, debug=_DEBUG))

  def head(self, *args):
    pass

  def get(self, *args):
    pass

  def post(self, *args):
    pass

class ViewHandler(BaseRequestHandler):
  def get(self, slug):
    content = Content().get_latest(slug)
    if (content):
      self.generate('view.html', { 'content': content })
    else:
      self.error(404)
      self.generate('view.html', { 'content': Content(
        title=config.content['errors']['http404']['title'],
        body=config.content['errors']['http404']['body']
      )})

class EditHandler (BaseRequestHandler):
  @login_required
  def get(self, slug):
    if not (users.is_current_user_admin() or \
      (users.get_current_user().email() in config.content['admins'])):
      self.error(403)
      self.generate('view.html', { 'content': Content(
        title=config.content['errors']['http403']['title'],
        body=config.content['errors']['http403']['body']
      )})
    else:
      content = Content().get_latest(slug)
      self.generate('edit.html', { 'form': ContentForm(instance=content) } )

  def post(self, slug):
    if not (users.is_current_user_admin() or \
      (users.get_current_user().email() in admins)):
      self.error(403)
      self.generate('view.html', { 'content':
        Content(
          title=config.content['errors']['http404']['title'],
          body=config.content['errors']['http404']['body']
        )})
    else:
      data = ContentForm(data=self.request.POST)
      if data.is_valid():
        content = data.save(commit=False)
        content.slug = slug
        content.put()
        self.redirect("/%s" % slug)
      else:
        self.generate('edit.html', { 'form': ContentForm(instance=content) })

class SitemapHandler(webapp.RequestHandler):

  def get(self):
    slugs = {}
    pages = Content.all()
    for page in pages:
      slugs[page.slug] = True
    self.response.headers['Content-Type'] = 'text/xml'
    self.response.out.write('''<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">''')
    for slug in slugs.keys():
        self.response.out.write("""<url>
  <loc>http://%s/%s</loc>
  <changefreq>%s</changefreq>
</url>""" % (self.request.headers['host'], slug,
      config.content['sitemap']['changefreq']))
    self.response.out.write('</urlset>')

def main():
  application = webapp.WSGIApplication([('/sitemap.xml', SitemapHandler),
                                        (r'/([^/]*)[/]?edit', EditHandler),
                                        (r'/(.*)', ViewHandler)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()
